home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH7 / SRC / PANVIEW2.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-05-01  |  13.8 KB  |  437 lines

  1. VERSION 4.00
  2. Begin VB.Form ViewportForm 
  3.    Caption         =   "Viewport"
  4.    ClientHeight    =   3165
  5.    ClientLeft      =   2550
  6.    ClientTop       =   1800
  7.    ClientWidth     =   3165
  8.    Height          =   3855
  9.    Left            =   2490
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   3165
  12.    ScaleWidth      =   3165
  13.    Top             =   1170
  14.    Width           =   3285
  15.    Begin VB.HScrollBar HScrollBar 
  16.       Height          =   255
  17.       Left            =   0
  18.       TabIndex        =   2
  19.       Top             =   2880
  20.       Width           =   2895
  21.    End
  22.    Begin VB.VScrollBar VScrollBar 
  23.       Height          =   2895
  24.       Left            =   2880
  25.       TabIndex        =   1
  26.       Top             =   0
  27.       Width           =   255
  28.    End
  29.    Begin VB.PictureBox viewport 
  30.       Height          =   2880
  31.       Left            =   0
  32.       ScaleHeight     =   2820
  33.       ScaleWidth      =   2820
  34.       TabIndex        =   0
  35.       Top             =   0
  36.       Width           =   2880
  37.    End
  38.    Begin VB.Menu mnuFile 
  39.       Caption         =   "&File"
  40.       Begin VB.Menu mnuFileExit 
  41.          Caption         =   "E&xit"
  42.       End
  43.    End
  44.    Begin VB.Menu mnuScale 
  45.       Caption         =   "&Scale"
  46.       Begin VB.Menu mnuScaleZoom 
  47.          Caption         =   "&Zoom"
  48.          Shortcut        =   ^Z
  49.       End
  50.       Begin VB.Menu mnuScaleMag 
  51.          Caption         =   "Full  Scale"
  52.          Index           =   1
  53.          Shortcut        =   ^F
  54.       End
  55.       Begin VB.Menu mnuScaleMag 
  56.          Caption         =   "Magnify 1/2"
  57.          Index           =   20
  58.          Shortcut        =   ^{F2}
  59.       End
  60.       Begin VB.Menu mnuScaleMag 
  61.          Caption         =   "Magnify 1/4"
  62.          Index           =   40
  63.          Shortcut        =   ^{F4}
  64.       End
  65.    End
  66. Attribute VB_Name = "ViewportForm"
  67. Attribute VB_Creatable = False
  68. Attribute VB_Exposed = False
  69. Option Explicit
  70. ' Global max and min world coordinates
  71. ' (including margins).
  72. Const DataXmin = 0
  73. Const DataXmax = 10
  74. Const DataYmin = 0
  75. Const DataYmax = 10
  76. ' Set the min and max allowed width and height.
  77. Const DataMinWid = 1
  78. Const DataMinHgt = 1
  79. Const DataMaxWid = DataXmax - DataXmin
  80. Const DataMaxHgt = DataYmax - DataYmin
  81. ' The aspect ratio of the viewport.
  82. Dim VAspect As Single
  83. ' Current world window bounds.
  84. Dim Wxmin As Single
  85. Dim Wxmax As Single
  86. Dim Wymin As Single
  87. Dim Wymax As Single
  88. ' Prevent change events when we are adjusting the
  89. ' scroll bars.
  90. Dim IgnoreSbarChange As Boolean
  91. ' Variables used for zooming.
  92. Dim DrawingMode As Integer
  93. Const MODE_NONE = 0
  94. Const MODE_START_ZOOM = 1
  95. Const MODE_ZOOMING = 2
  96. Dim StartX As Single
  97. Dim StartY As Single
  98. Dim LastX As Single
  99. Dim LastY As Single
  100. Dim OldMode As Integer
  101. ' ************************************************
  102. ' Draw a smiley face in the viewport centered
  103. ' around the point (5, 5).
  104. ' ************************************************
  105. Sub DrawSmiley()
  106. Const pi = 3.14159265
  107. Const pi2 = 2 * pi
  108. Dim i As Single
  109.     Viewport.Circle (5, 5), 4            ' Head
  110.     Viewport.Circle (5, 5), 3, , pi, pi2 ' Smile
  111.     Viewport.Circle (3, 7), 0.75         ' Left eye.
  112.     Viewport.Circle (7, 7), 0.75         ' Right eye.
  113.     Viewport.Circle (5, 5), 0.75         ' Nose.
  114.     ' Draw some grid lines to make small scales
  115.     ' easier to understand.
  116.     i = DataXmin + 0.5
  117.     Do While i < DataXmax
  118.         Viewport.Line (i, DataYmin)-(i, DataYmax)
  119.         i = i + 0.5
  120.     Loop
  121.     i = DataYmin + 0.5
  122.     Do While i < DataYmax
  123.         Viewport.Line (DataXmin, i)-(DataXmax, i)
  124.         i = i + 0.5
  125.     Loop
  126. End Sub
  127. ' ************************************************
  128. ' End a zoom operation early. This happens if the
  129. ' user starts a zoom and the selects another menu
  130. ' item instead of doing the zoom.
  131. ' ************************************************
  132. Sub StopZoom()
  133.     If DrawingMode <> MODE_START_ZOOM Then Exit Sub
  134.     DrawingMode = MODE_NONE
  135.     Viewport.DrawMode = OldMode
  136.     Viewport.MousePointer = vbDefault
  137. End Sub
  138. ' ************************************************
  139. ' Change the level of magnification.
  140. ' ************************************************
  141. Sub SetScaleFactor(fact As Single)
  142. Dim wid As Single
  143. Dim hgt As Single
  144. Dim mid As Single
  145.     fact = 1 / fact
  146.     ' Compute the new world window size.
  147.     wid = fact * (Wxmax - Wxmin)
  148.     hgt = fact * (Wymax - Wymin)
  149.     ' Center the new world window over the old.
  150.     mid = (Wxmax + Wxmin) / 2
  151.     Wxmin = mid - wid / 2
  152.     Wxmax = mid + wid / 2
  153.     mid = (Wymax + Wymin) / 2
  154.     Wymin = mid - hgt / 2
  155.     Wymax = mid + hgt / 2
  156.     ' Set the new world window bounds.
  157.     SetWorldWindow
  158. End Sub
  159. ' ************************************************
  160. ' Adjust the world window so it is not too big,
  161. ' too small, off to one side, or of the wrong
  162. ' aspect ratio. Then map the world window to the
  163. ' viewport and force the viewport to repaint.
  164. ' ************************************************
  165. Sub SetWorldWindow()
  166. Dim wid As Single
  167. Dim hgt As Single
  168. Dim xmid As Single
  169. Dim ymid As Single
  170. Dim aspect As Single
  171.     wid = Wxmax - Wxmin
  172.     xmid = (Wxmax + Wxmin) / 2
  173.     hgt = Wymax - Wymin
  174.     ymid = (Wymax + Wymin) / 2
  175.         
  176.     ' Make sure we're not too big or too small.
  177.     If wid > DataMaxWid Then
  178.         wid = DataMaxWid
  179.     ElseIf wid < DataMinWid Then
  180.         wid = DataMinWid
  181.     End If
  182.     If hgt > DataMaxHgt Then
  183.         hgt = DataMaxHgt
  184.     ElseIf hgt < DataMinHgt Then
  185.         hgt = DataMinHgt
  186.     End If
  187.     ' Make the aspect ratio match the
  188.     ' viewport aspect ratio.
  189.     aspect = hgt / wid
  190.     If aspect > VAspect Then
  191.         ' Too tall and thin. Make it wider.
  192.         wid = hgt / VAspect
  193.     Else
  194.         ' Too short and wide. Make it taller.
  195.         hgt = wid * VAspect
  196.     End If
  197.     ' Compute the new coordinates
  198.     Wxmin = xmid - wid / 2
  199.     Wxmax = xmid + wid / 2
  200.     Wymin = ymid - hgt / 2
  201.     Wymax = ymid + hgt / 2
  202.     ' Check that we're not off to one side.
  203.     If wid > DataMaxWid Then
  204.         ' We're wider than the picture. Center.
  205.         xmid = (DataXmax + DataXmin) / 2
  206.         Wxmin = xmid - wid / 2
  207.         Wxmax = xmid + wid / 2
  208.     Else
  209.         ' Else see if we're too far to one side.
  210.         If Wxmin < DataXmin And Wxmax < DataXmax Then
  211.             ' Adjust to the right.
  212.             Wxmax = Wxmax + DataXmin - Wxmin
  213.             Wxmin = DataXmin
  214.         End If
  215.         If Wxmax > DataXmax And Wxmin > DataXmin Then
  216.             ' Adjust to the left.
  217.             Wxmin = Wxmin + DataXmax - Wxmax
  218.             Wxmax = DataXmax
  219.         End If
  220.     End If
  221.     If hgt > DataMaxHgt Then
  222.         ' We're taller than the picture. Center.
  223.         ymid = (DataYmax + DataYmin) / 2
  224.         Wymin = ymid - hgt / 2
  225.         Wymax = ymid + hgt / 2
  226.     Else
  227.         ' See if we're too far to top or bottom.
  228.         If Wymin < DataYmin And Wymax < DataYmax Then
  229.             ' Adjust downward.
  230.             Wymax = Wymax + DataYmin - Wymin
  231.             Wymin = DataYmin
  232.         End If
  233.         If Wymax > DataYmax And Wymin > DataYmin Then
  234.             ' Adjust upward.
  235.             Wymin = Wymin + DataYmax - Wymax
  236.             Wymax = DataYmax
  237.         End If
  238.     End If
  239.     ' Map the world window to the viewport.
  240.     Viewport.Scale (Wxmin, Wymax)-(Wxmax, Wymin)
  241.     ' Force the viewport to repaint.
  242.     Viewport.Refresh
  243.         
  244.     ' Reset the scroll bars.
  245.     IgnoreSbarChange = True
  246.     HScrollBar.Visible = (wid < DataXmax - DataXmin)
  247.     VScrollBar.Visible = (hgt < DataYmax - DataYmin)
  248.     ' The values of the scroll bars will be where
  249.     ' the top/left of the world window should be.
  250.     VScrollBar.Min = 100 * (DataYmax)
  251.     VScrollBar.Max = 100 * (DataYmin + hgt)
  252.     HScrollBar.Min = 100 * (DataXmin)
  253.     HScrollBar.Max = 100 * (DataXmax - wid)
  254.     ' SmallChange moves the world window 1/10
  255.     ' of its width/height. Large change moves it
  256.     ' 9/10 of its width/height.
  257.     VScrollBar.SmallChange = 100 * (hgt / 10)
  258.     VScrollBar.LargeChange = 100 * (9 * hgt / 10)
  259.     HScrollBar.SmallChange = 100 * (wid / 10)
  260.     HScrollBar.LargeChange = 100 * (9 * wid / 10)
  261.     ' Set the current scroll bar values.
  262.     VScrollBar.Value = 100 * Wymax
  263.     HScrollBar.Value = 100 * Wxmin
  264.     IgnoreSbarChange = False
  265. End Sub
  266. ' ************************************************
  267. ' Return to the default magnification scale.
  268. ' ************************************************
  269. Sub SetScaleFull()
  270.     ' Reset the world window coordinates.
  271.     Wxmin = DataXmin
  272.     Wxmax = DataXmax
  273.     Wymin = DataYmin
  274.     Wymax = DataYmax
  275.     ' Set the new world window bounds.
  276.     SetWorldWindow
  277. End Sub
  278. Private Sub Form_Resize()
  279. Dim X As Single
  280. Dim Y As Single
  281. Dim wid As Single
  282. Dim hgt As Single
  283.     ' Fit the viewport to the window.
  284.     X = Viewport.Left
  285.     Y = Viewport.Top
  286.     wid = ScaleWidth - 2 * X - VScrollBar.Width
  287.     hgt = ScaleHeight - 2 * Y - HScrollBar.Height
  288.     Viewport.Move X, Y, wid, hgt
  289.     VAspect = hgt / wid
  290.     ' Place the scroll bars next to the viewport.
  291.     X = Viewport.Left + Viewport.Width + 10
  292.     Y = Viewport.Top
  293.     wid = VScrollBar.Width
  294.     hgt = Viewport.Height
  295.     VScrollBar.Move X, Y, wid, hgt
  296.     X = Viewport.Left
  297.     Y = Viewport.Top + Viewport.Height + 10
  298.     wid = Viewport.Width
  299.     hgt = HScrollBar.Height
  300.     HScrollBar.Move X, Y, wid, hgt
  301.     ' Start at full scale.
  302.     SetScaleFull
  303. End Sub
  304. ' ************************************************
  305. ' Move the world window.
  306. ' ************************************************
  307. Private Sub HScrollBar_Change()
  308.     If IgnoreSbarChange Then Exit Sub
  309.     HScrollBarChanged
  310. End Sub
  311. ' ************************************************
  312. ' The vertical scroll bar has been moved. Adjust
  313. ' the world window.
  314. ' ************************************************
  315. Sub VScrollBarChanged()
  316. Dim hgt As Single
  317.     hgt = Wymax - Wymin
  318.     Wymax = VScrollBar.Value / 100
  319.     Wymin = Wymax - hgt
  320.     ' Remap the world window.
  321.     IgnoreSbarChange = True
  322.     SetWorldWindow
  323.     IgnoreSbarChange = False
  324. End Sub
  325. ' ************************************************
  326. ' The horizontal scroll bar has been moved. Adjust
  327. ' the world window.
  328. ' ************************************************
  329. Sub HScrollBarChanged()
  330. Dim wid As Single
  331.     wid = Wxmax - Wxmin
  332.     Wxmin = HScrollBar.Value / 100
  333.     Wxmax = Wxmin + wid
  334.     ' Remap the world window.
  335.     IgnoreSbarChange = True
  336.     SetWorldWindow
  337.     IgnoreSbarChange = False
  338. End Sub
  339. Private Sub mnuFileExit_Click()
  340.     StopZoom    ' If we're zooming, stop it.
  341.     Unload Me
  342. End Sub
  343. ' ************************************************
  344. ' Change the level of magnification.
  345. ' ************************************************
  346. Private Sub mnuScaleMag_Click(Index As Integer)
  347.     StopZoom    ' If we're zooming, stop it.
  348.     If Index = 1 Then
  349.         ' Return to full scale.
  350.         SetScaleFull
  351.     ElseIf Index < 10 Then
  352.         ' Magnify by the indicated amount.
  353.         SetScaleFactor CSng(Index)
  354.     Else
  355.         ' Zoom out by 1/(Index \ 10).
  356.         SetScaleFactor 1 / (Index \ 10)
  357.     End If
  358. End Sub
  359. ' ************************************************
  360. ' Allow the user to select an area to zoom in on.
  361. ' ************************************************
  362. Private Sub mnuScaleZoom_Click()
  363.     ' Enable zooming.
  364.     Viewport.MousePointer = vbCrosshair
  365.     DrawingMode = MODE_START_ZOOM
  366. End Sub
  367. ' ************************************************
  368. ' If we are zooming, start the rubberband box.
  369. ' ************************************************
  370. Private Sub Viewport_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  371.     If DrawingMode <> MODE_START_ZOOM Then Exit Sub
  372.     DrawingMode = MODE_ZOOMING
  373.     OldMode = Viewport.DrawMode
  374.     Viewport.DrawMode = vbInvert
  375.     StartX = X
  376.     StartY = Y
  377.     LastX = X
  378.     LastY = Y
  379.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  380. End Sub
  381. ' ************************************************
  382. ' If we are zooming, continue the rubberband box.
  383. ' ************************************************
  384. Private Sub Viewport_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  385.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  386.     ' Erase the old box.
  387.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  388.     ' Draw the new box.
  389.     LastX = X
  390.     LastY = Y
  391.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  392. End Sub
  393. ' ************************************************
  394. ' If we are zooming, finish the rubberband box.
  395. ' ************************************************
  396. Private Sub Viewport_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  397. Dim wid As Single
  398. Dim hgt As Single
  399. Dim mid As Single
  400.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  401.     DrawingMode = MODE_NONE
  402.     ' Erase the old box.
  403.     Viewport.Line (StartX, StartY)-(LastX, LastY), , B
  404.     LastX = X
  405.     LastY = Y
  406.     ' We're done drawing for this rubberband box.
  407.     Viewport.DrawMode = OldMode
  408.     Viewport.MousePointer = vbDefault
  409.     ' Set the new world window bounds.
  410.     If StartX > LastX Then
  411.         Wxmin = LastX
  412.         Wxmax = StartX
  413.     Else
  414.         Wxmin = StartX
  415.         Wxmax = LastX
  416.     End If
  417.     If StartY > LastY Then
  418.         Wymin = LastY
  419.         Wymax = StartY
  420.     Else
  421.         Wymin = StartY
  422.         Wymax = LastY
  423.     End If
  424.     ' Set the new world window bounds.
  425.     SetWorldWindow
  426. End Sub
  427. Private Sub Viewport_Paint()
  428.     DrawSmiley
  429. End Sub
  430. ' ************************************************
  431. ' Move the world window.
  432. ' ************************************************
  433. Private Sub VScrollBar_Change()
  434.     If IgnoreSbarChange Then Exit Sub
  435.     VScrollBarChanged
  436. End Sub
  437.